package value;

import globals.CentralStatics;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;

import problems.Actions;

public class SimpleVector<A> implements Vector, Taggable<A> {

	private A theTag;
	protected double[] value;
	protected int index = 0;
	
	public SimpleVector(int n){
		this.value=new double [n];
		for(int i=0; i<n; i++){
			this.value[i]=0;
		}
	}
	
	public SimpleVector(String s){
		String[] strs = s.split(",");
		this.value=new double [strs.length];
		for(int i=0; i<strs.length; i++){
			this.value[i]=Double.parseDouble(strs[i]);
		}
	}
	
	protected SimpleVector(){
		this.value = null;
		this.index = 0;
	}
	
	public SimpleVector(double[] value2) {
		this.value=new double [value2.length];
		for(int i=0; i<value2.length; i++){
			this.value[i]=value2[i];
		}
	}

	public SimpleVector(ValueAtBeliefVector<A> vb) {
		this(vb.value);
		/////////////////////////////////////////////changed assignment
		this.theTag=vb.retrieveTags().get(0);
		
	}

	@Override
	public Iterator<Double> iterator () {
		index = 0;
		return this;
	}

	@Override
	public boolean hasNext() {
		return index < value.length;
	}

	@Override
	public Double next() {
		return value[index ++];
	}

	@Override
	public void remove() {
		System.err.println("Do not use SimpleVector.remove()");
	}

	@Override
	public double linearScalValue(double[] wvec) {
		return CentralStatics.innerProduct(value, wvec);
	}

	@Override
	public boolean equalValues(Vector v) {
		return CentralStatics.equalVectors(value, v.getValue());
	}

	@Override
	public boolean weakParetoDominates(Vector v) {
		return CentralStatics.weakParetoDominates(value, v.getValue());
	}

	@Override
	public boolean paretoDominates(Vector v) {
		if(this.equals(v)){
			return false;
		} else {
			return this.weakParetoDominates(v);
		}
	}

	@Override
	public void setValue(double[] vec) {
		this.value=vec;
	}

	@Override
	public double[] getValue() {
		return this.value;
	}

	@Override
	public int length() {
		return this.value.length;
	}

	@Override
	public void setValue(int i, double val) {
		this.value[i]=val;
	}

	@Override
	public double getValue(int i) {
		return this.value[i];
	}

	//NB: returns a NEW vector, does not change current one
	public SimpleVector<A> add(SimpleVector<?> v2){
		SimpleVector<A> sv = new SimpleVector<A>(this.length());
		sv.setValue(CentralStatics.addVec(this.getValue(), v2.getValue()));
		return sv;
	}
	
	public void process(){
		System.err.println("Nothing to process, called SimpleVector method.");
	}

	public SimpleVector<A> copyMatrix(AlphaMatrix<A> v) {
		SimpleVector<A> sv = new SimpleVector<A>(v.length());
		sv.setValue(v.getValue());
		return sv;
	}
	
	@Override
	public SimpleVector<A> zeroVector() {
		SimpleVector<A> sv = new SimpleVector<A>(this.length());
		return sv;
	}
	
	@Override
	public SimpleVector<A> linearTransformation(double[][] trans) {
		if(trans.length!=this.length()){
			System.err.println("inapplicable transformation");
			System.exit(-239);
		}
		SimpleVector<A> sv = new SimpleVector<A>(this.length());
		for(int i=0; i<trans.length; i++){
			for(int j=0; j<trans[i].length; j++){
				sv.setValue(i, sv.getValue(i)+this.getValue(j)*trans[i][j]);
			}
		}
		return sv;
	}

	@Override
	public void tag(A t) {
		this.theTag = t;
	}

	@Override
	public void tag(ArrayList<A> tl) {
		
		///changed it for checking purpose
		System.err.println("Value should only be tagged with one action in A.");
		System.err.println("Tagging with the first action in the list.");
		System.err.println("Tagging this type of vector should never be done manually.");
		System.out.println("Tagging this type of vector should never be done manually.");
		this.theTag = tl.get(0);
	}

	@Override
	public ArrayList<A> retrieveTags() {
		ArrayList<A> lst = new ArrayList<A>(1);
		System.out.println("Tag Value"+theTag);
		lst.add(theTag);
		return lst;
	}
	
	public String toString(){
		String result = "";
		for(int s=0; s<this.length(); s++){
			result+=this.getValue(s);
			if(s!=this.length()-1){
				result+=",";
			}
		}
		return result;
	}
	
	public String toString(String[] states, Actions<A> acts){
		DecimalFormat format = new DecimalFormat("###.##");
		String result = "Action: ";
		result+="\n";
		for(int s=0; s<this.length(); s++){
			result+=states[s]+": ";
			result+=format.format(this.getValue(s))+"\n";
		}
		return result;
	}

	@Override
	public void multiplyByScalar(double scalar) {
		for(int i=0; i<this.value.length; i++){
			this.value[i] *= scalar;
		}
	}

	@Override
	public String className() {
		return "SimpleVector";
	}
}
